1 import pygame
2 import time
3 import random
4
5 pygame.init()
6
7 display_width = 800
8 display_height = 600
9
10 gameDisplay = pygame.display.set_mode((display_width, display_height))
11
12
13 pygame.display.set_caption('Tank Destroyer Game')
14
15
16 wheat=(245,222,179)
17
18 white = (255, 255, 255)
19 black = (0, 0, 0)
20 blue = (0,0,255)
21
22 red = (200, 0, 0)
23 light_red = (255, 0, 0)
24 pink=(255,192,203)
25 yellow = (200, 200, 0)
26 light_yellow = (255, 255, 0)
27
28 green = (34, 177, 76)
29 light_green = (0, 255, 0)
30
31 clock = pygame.time.Clock()
32
33 tankWidth = 40
34 tankHeight = 20
35
36 turretWidth = 5
37 wheelWidth = 5
38
39 ground_height = 35
40
41 smallfont = pygame.font.SysFont("comicsansms", 25)
42 medfont = pygame.font.SysFont("comicsansms", 50)
43 largefont = pygame.font.SysFont("Times new Roman", 85)
44 vsmallfont = pygame.font.SysFont("Times new Roman", 25)
45
46 def score(score):
47 text = smallfont.render("Score: " + str(score), True, white)
48 gameDisplay.blit(text, [0, 0])
49
50 def text_objects(text, color, size="small"):
51 if size == "small":
52 textSurface = smallfont.render(text, True, color)
53 if size == "medium":
54 textSurface = medfont.render(text, True, color)
55 if size == "large":
56 textSurface = largefont.render(text, True, color)
57 if size == "vsmall":
58 textSurface = vsmallfont.render(text, True, color)
59
60 return textSurface, textSurface.get_rect()
61
62 def text_to_button(msg, color, buttonx, buttony, buttonwidth, buttonheight, size="vsmall"):
63 textSurf, textRect = text_objects(msg, color, size)
64 textRect.center = ((buttonx + (buttonwidth / 2)), buttony + (buttonheight / 2))
65 gameDisplay.blit(textSurf, textRect)
66
67 def message_to_screen(msg, color, y_displace=0, size="small"):
68 textSurf, textRect = text_objects(msg, color, size)
69 textRect.center = (int(display_width / 2), int(display_height / 2) + y_displace)
70 gameDisplay.blit(textSurf, textRect)
71
72 def tank(x, y, turPos):
73 x = int(x)
74 y = int(y)
75
76 possibleTurrets = [(x - 27, y - 2),
77 (x - 26, y - 5),
78 (x - 25, y - 8),
79 (x - 23, y - 12),
80 (x - 20, y - 14),
81 (x - 18, y - 15),
82 (x - 15, y - 17),
83 (x - 13, y - 19),
84 (x - 11, y - 21)
85 ]
86
87 pygame.draw.circle(gameDisplay, pink, (x, y), int(tankHeight / 2))
88 pygame.draw.rect(gameDisplay, pink, (x - tankHeight, y, tankWidth, tankHeight))
89
90 pygame.draw.line(gameDisplay, pink, (x, y), possibleTurrets[turPos], turretWidth)
91
92 pygame.draw.circle(gameDisplay, pink, (x - 15, y + 20), wheelWidth)
93 pygame.draw.circle(gameDisplay, pink, (x - 10, y + 20), wheelWidth)
94
95 pygame.draw.circle(gameDisplay, pink, (x - 15, y + 20), wheelWidth)
96 pygame.draw.circle(gameDisplay, pink, (x - 10, y + 20), wheelWidth)
97 pygame.draw.circle(gameDisplay, pink, (x - 5, y + 20), wheelWidth)
98 pygame.draw.circle(gameDisplay, pink, (x, y + 20), wheelWidth)
99 pygame.draw.circle(gameDisplay, pink, (x + 5, y + 20), wheelWidth)
100 pygame.draw.circle(gameDisplay, pink, (x + 10, y + 20), wheelWidth)
101 pygame.draw.circle(gameDisplay, pink, (x + 15, y + 20), wheelWidth)
102
103 return possibleTurrets[turPos]
104
105 def enemy_tank(x, y, turPos):
106 x = int(x)
107 y = int(y)
108
109 possibleTurrets = [(x + 27, y - 2),
110 (x + 26, y - 5),
111 (x + 25, y - 8),
112 (x + 23, y - 12),
113 (x + 20, y - 14),
114 (x + 18, y - 15),
115 (x + 15, y - 17),
116 (x + 13, y - 19),
117 (x + 11, y - 21)
118 ]
119
120 pygame.draw.circle(gameDisplay, blue, (x, y), int(tankHeight / 2))
121 pygame.draw.rect(gameDisplay, blue, (x - tankHeight, y, tankWidth, tankHeight))
122
123 pygame.draw.line(gameDisplay, blue, (x, y), possibleTurrets[turPos], turretWidth)
124
125 pygame.draw.circle(gameDisplay, blue, (x - 15, y + 20), wheelWidth)
126 pygame.draw.circle(gameDisplay, blue, (x - 10, y + 20), wheelWidth)
127
128 pygame.draw.circle(gameDisplay, blue, (x - 15, y + 20), wheelWidth)
129 pygame.draw.circle(gameDisplay, blue, (x - 10, y + 20), wheelWidth)
130 pygame.draw.circle(gameDisplay, blue, (x - 5, y + 20), wheelWidth)
131 pygame.draw.circle(gameDisplay, blue, (x, y + 20), wheelWidth)
132 pygame.draw.circle(gameDisplay, blue, (x + 5, y + 20), wheelWidth)
133 pygame.draw.circle(gameDisplay, blue, (x + 10, y + 20), wheelWidth)
134 pygame.draw.circle(gameDisplay, blue, (x + 15, y + 20), wheelWidth)
135
136 return possibleTurrets[turPos]
137
138 def game_controls():
139 gcont = True
140
141 while gcont:
142 for event in pygame.event.get():
143
144 if event.type == pygame.QUIT:
145 pygame.quit()
146 quit()
147
148 gameDisplay.fill(black)
149 message_to_screen("Controls", white, -100, size="large")
150 message_to_screen("Fire: Spacebar", wheat, -30)
151 message_to_screen("Move Turret: Up and Down arrows", wheat, 10)
152 message_to_screen("Move Tank: Left and Right arrows", wheat, 50)
153 message_to_screen("Press D to raise Power % AND Press A to lower Power % ", wheat, 140)
154 message_to_screen("Pause: P", wheat, 90)
155
156 button("Play", 150, 500, 100, 50, green, light_green, action="play")
157 button("Main", 350, 500, 100, 50, yellow, light_yellow, action="main")
158 button("Quit", 550, 500, 100, 50, red, light_red, action="quit")
159
160 pygame.display.update()
161
162 clock.tick(15)
163
164 def button(text, x, y, width, height, inactive_color, active_color, action=None,size=" "):
165 cur = pygame.mouse.get_pos()
166 click = pygame.mouse.get_pressed()
167
168 if x + width > cur[0] > x and y + height > cur[1] > y:
169 pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
170 if click[0] == 1 and action != None:
171 if action == "quit":
172 pygame.quit()
173 quit()
174
175 if action == "controls":
176 game_controls()
177
178 if action == "play":
179 gameLoop()
180
181 if action == "main":
182 game_intro()
183
184 else:
185 pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))
186
187 text_to_button(text, black, x, y, width, height)
188
189 def pause():
190 paused = True
191 message_to_screen("Paused", white, -100, size="large")
192 message_to_screen("Press C to continue playing or Q to quit", wheat, 25)
193 pygame.display.update()
194 while paused:
195
196 for event in pygame.event.get():
197
198 if event.type == pygame.QUIT:
199 pygame.quit()
200 quit()
201 if event.type == pygame.KEYDOWN:
202 if event.key == pygame.K_c:
203 paused = False
204 elif event.key == pygame.K_q:
205 pygame.quit()
206 quit()
207
208 clock.tick(5)
209
210 def barrier(xlocation, randomHeight, barrier_width):
211 pygame.draw.rect(gameDisplay, green, [xlocation, display_height - randomHeight, barrier_width, randomHeight])
212
213 def explosion(x, y, size=50):
214
215 explode = True
216
217 while explode:
218 for event in pygame.event.get():
219 if event.type == pygame.QUIT:
220 pygame.quit()
221 quit()
222
223 startPoint = x, y
224
225 colorChoices = [red, light_red, yellow, light_yellow]
226
227 magnitude = 1
228
229 while magnitude < size:
230 exploding_bit_x = x + random.randrange(-1 * magnitude, magnitude)
231 exploding_bit_y = y + random.randrange(-1 * magnitude, magnitude)
232
233 pygame.draw.circle(gameDisplay, colorChoices[random.randrange(0, 4)], (exploding_bit_x, exploding_bit_y),
234 random.randrange(1, 5))
235 magnitude += 1
236
237 pygame.display.update()
238 clock.tick(100)
239
240 explode = False
241
242 def fireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, enemyTankX, enemyTankY):
243
244 fire = True
245 damage = 0
246
247 startingShell = list(xy)
248
249 print("FIRE!", xy)
250
251 while fire:
252 for event in pygame.event.get():
253 if event.type == pygame.QUIT:
254 pygame.quit()
255 quit()
256
257 pygame.draw.circle(gameDisplay, red, (startingShell[0], startingShell[1]), 5)
258
259 startingShell[0] -= (12 - turPos) * 2
260
261
262 startingShell[1] += int(
263 (((startingShell[0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
264
265 if startingShell[1] > display_height - ground_height:
266 print("Last shell:", startingShell[0], startingShell[1])
267 hit_x = int((startingShell[0] * display_height - ground_height) / startingShell[1])
268 hit_y = int(display_height - ground_height)
269 print("Impact:", hit_x, hit_y)
270
271 if enemyTankX + 10 > hit_x > enemyTankX - 10:
272 print("Critical Hit!")
273 damage = 25
274 elif enemyTankX + 15 > hit_x > enemyTankX - 15:
275 print("Hard Hit!")
276 damage = 18
277 elif enemyTankX + 25 > hit_x > enemyTankX - 25:
278 print("Medium Hit")
279 damage = 10
280 elif enemyTankX + 35 > hit_x > enemyTankX - 35:
281 print("Light Hit")
282 damage = 5
283
284 explosion(hit_x, hit_y)
285 fire = False
286
287 check_x_1 = startingShell[0] <= xlocation + barrier_width
288 check_x_2 = startingShell[0] >= xlocation
289
290 check_y_1 = startingShell[1] <= display_height
291 check_y_2 = startingShell[1] >= display_height - randomHeight
292
293 if check_x_1 and check_x_2 and check_y_1 and check_y_2:
294 print("Last shell:", startingShell[0], startingShell[1])
295 hit_x = int((startingShell[0]))
296 hit_y = int(startingShell[1])
297 print("Impact:", hit_x, hit_y)
298 explosion(hit_x, hit_y)
299 fire = False
300
301 pygame.display.update()
302 clock.tick(60)
303 return damage
304
305 def e_fireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, ptankx, ptanky):
306
307 damage = 0
308 currentPower = 1
309 power_found = False
310
311 while not power_found:
312 currentPower += 1
313 if currentPower > 100:
314 power_found = True
315 # print(currentPower)
316
317 fire = True
318 startingShell = list(xy)
319
320 while fire:
321 for event in pygame.event.get():
322 if event.type == pygame.QUIT:
323 pygame.quit()
324 quit()
325
326
327 startingShell[0] += (12 - turPos) * 2
328 startingShell[1] += int(
329 (((startingShell[0] - xy[0]) * 0.015 / (currentPower / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
330
331 if startingShell[1] > display_height - ground_height:
332 hit_x = int((startingShell[0] * display_height - ground_height) / startingShell[1])
333 hit_y = int(display_height - ground_height)
334
335 if ptankx + 15 > hit_x > ptankx - 15:
336 print("target acquired!")
337 power_found = True
338 fire = False
339
340 check_x_1 = startingShell[0] <= xlocation + barrier_width
341 check_x_2 = startingShell[0] >= xlocation
342
343 check_y_1 = startingShell[1] <= display_height
344 check_y_2 = startingShell[1] >= display_height - randomHeight
345
346 if check_x_1 and check_x_2 and check_y_1 and check_y_2:
347 hit_x = int((startingShell[0]))
348 hit_y = int(startingShell[1])
349
350 fire = False
351
352 fire = True
353 startingShell = list(xy)
354 print("FIRE!", xy)
355
356 while fire:
357 for event in pygame.event.get():
358 if event.type == pygame.QUIT:
359 pygame.quit()
360 quit()
361
362 pygame.draw.circle(gameDisplay, red, (startingShell[0], startingShell[1]), 5)
363
364 startingShell[0] += (12 - turPos) * 2
365
366
367
368 gun_power = random.randrange(int(currentPower * 0.90), int(currentPower * 1.10))
369
370 startingShell[1] += int(
371 (((startingShell[0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos)))
372
373 if startingShell[1] > display_height - ground_height:
374 print("last shell:", startingShell[0], startingShell[1])
375 hit_x = int((startingShell[0] * display_height - ground_height) / startingShell[1])
376 hit_y = int(display_height - ground_height)
377 print("Impact:", hit_x, hit_y)
378
379 if ptankx + 10 > hit_x > ptankx - 10:
380 print("Critical Hit!")
381 damage = 25
382 elif ptankx + 15 > hit_x > ptankx - 15:
383 print("Hard Hit!")
384 damage = 18
385 elif ptankx + 25 > hit_x > ptankx - 25:
386 print("Medium Hit")
387 damage = 10
388 elif ptankx + 35 > hit_x > ptankx - 35:
389 print("Light Hit")
390 damage = 5
391
392 explosion(hit_x, hit_y)
393 fire = False
394
395 check_x_1 = startingShell[0] <= xlocation + barrier_width
396 check_x_2 = startingShell[0] >= xlocation
397
398 check_y_1 = startingShell[1] <= display_height
399 check_y_2 = startingShell[1] >= display_height - randomHeight
400
401 if check_x_1 and check_x_2 and check_y_1 and check_y_2:
402 print("Last shell:", startingShell[0], startingShell[1])
403 hit_x = int((startingShell[0]))
404 hit_y = int(startingShell[1])
405 print("Impact:", hit_x, hit_y)
406 explosion(hit_x, hit_y)
407 fire = False
408
409 pygame.display.update()
410 clock.tick(60)
411 return damage
412
413 def power(level):
414 text = smallfont.render("Power: " + str(level) + "%", True, wheat)
415 gameDisplay.blit(text, [display_width / 2, 0])
416
417 def game_intro():
418 intro = True
419
420 while intro:
421 for event in pygame.event.get():
422 if event.type == pygame.QUIT:
423 pygame.quit()
424 quit()
425
426 if event.type == pygame.KEYDOWN:
427 if event.key == pygame.K_c:
428 intro = False
429 elif event.key == pygame.K_q:
430
431 pygame.quit()
432 quit()
433
434 gameDisplay.fill(black)
435 message_to_screen("Tank Destroyer Game", white, -100, size="large")
436 message_to_screen("Shoot and dominate your enemy tank", wheat, 15)
437 message_to_screen("Bring glory for your homeland", wheat, 45)
438 button("Play", 150, 500, 100, 50, wheat, light_green, action="play",size="vsmall")
439 button("Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls",size="vsmall")
440 button("Quit", 550, 500, 100, 50, wheat, light_red, action="quit",size="vsmall")
441
442 pygame.display.update()
443
444 clock.tick(15)
445
446 def game_over():
447 game_over = True
448
449 while game_over:
450 for event in pygame.event.get():
451
452 if event.type == pygame.QUIT:
453 pygame.quit()
454 quit()
455
456 gameDisplay.fill(black)
457 message_to_screen("Game Over", white, -100, size="large")
458 message_to_screen("You died.", wheat, -30)
459
460 button("Play Again", 150, 500, 150, 50, wheat, light_green, action="play")
461 button("Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls")
462 button("Quit", 550, 500, 100, 50, wheat, light_red, action="quit")
463
464 pygame.display.update()
465
466 clock.tick(15)
467
468 def you_win():
469 win = True
470
471 while win:
472 for event in pygame.event.get():
473
474 if event.type == pygame.QUIT:
475 pygame.quit()
476 quit()
477
478 gameDisplay.fill(black)
479 message_to_screen("You won!", white, -100, size="large")
480 message_to_screen("Congratulations!", wheat, -30)
481
482 button("Play Again", 150, 500, 150, 50, wheat, light_green, action="play")
483 button("Controls", 350, 500, 100, 50, wheat, light_yellow, action="controls")
484 button("Quit", 550, 500, 100, 50, wheat, light_red, action="quit")
485
486 pygame.display.update()
487
488 clock.tick(15)
489
490 def health_bars(player_health, enemy_health):
491 if player_health > 75:
492 player_health_color = white
493 elif player_health > 50:
494 player_health_color = yellow
495 else:
496 player_health_color = red
497
498 if enemy_health > 75:
499 enemy_health_color = white
500 elif enemy_health > 50:
501 enemy_health_color = yellow
502 else:
503 enemy_health_color = red
504
505 pygame.draw.rect(gameDisplay, player_health_color, (680, 25, player_health, 25))
506 pygame.draw.rect(gameDisplay, enemy_health_color, (20, 25, enemy_health, 25))
507
508 def gameLoop():
509 gameExit = False
510 gameOver = False
511 FPS = 15
512
513 player_health = 100
514 enemy_health = 100
515
516 barrier_width = 50
517
518 mainTankX = display_width * 0.9
519 mainTankY = display_height * 0.9
520 tankMove = 0
521 currentTurPos = 0
522 changeTur = 0
523
524 enemyTankX = display_width * 0.1
525 enemyTankY = display_height * 0.9
526
527 fire_power = 50
528 power_change = 0
529
530 xlocation = (display_width / 2) + random.randint(-0.1 * display_width, 0.1 * display_width)
531 randomHeight = random.randrange(display_height * 0.1, display_height * 0.6)
532
533 while not gameExit:
534
535 if gameOver == True:
536
537 message_to_screen("Game Over", red, -50, size="large")
538 message_to_screen("Press C to play again or Q to exit", black, 50)
539 pygame.display.update()
540 while gameOver == True:
541 for event in pygame.event.get():
542 if event.type == pygame.QUIT:
543 gameExit = True
544 gameOver = False
545
546 if event.type == pygame.KEYDOWN:
547 if event.key == pygame.K_c:
548 gameLoop()
549 elif event.key == pygame.K_q:
550
551 gameExit = True
552 gameOver = False
553
554 for event in pygame.event.get():
555
556 if event.type == pygame.QUIT:
557 gameExit = True
558
559 if event.type == pygame.KEYDOWN:
560 if event.key == pygame.K_LEFT:
561 tankMove = -5
562
563 elif event.key == pygame.K_RIGHT:
564 tankMove = 5
565
566 elif event.key == pygame.K_UP:
567 changeTur = 1
568
569 elif event.key == pygame.K_DOWN:
570 changeTur = -1
571
572 elif event.key == pygame.K_p:
573 pause()
574
575 elif event.key == pygame.K_SPACE:
576
577 damage = fireShell(gun, mainTankX, mainTankY, currentTurPos, fire_power, xlocation, barrier_width,
578 randomHeight, enemyTankX, enemyTankY)
579 enemy_health -= damage
580
581 possibleMovement = ['f', 'r']
582 moveIndex = random.randrange(0, 2)
583
584 for x in range(random.randrange(0, 10)):
585
586 if display_width * 0.3 > enemyTankX > display_width * 0.03:
587 if possibleMovement[moveIndex] == "f":
588 enemyTankX += 5
589 elif possibleMovement[moveIndex] == "r":
590 enemyTankX -= 5
591
592 gameDisplay.fill(black)
593 health_bars(player_health, enemy_health)
594 gun = tank(mainTankX, mainTankY, currentTurPos)
595 enemy_gun = enemy_tank(enemyTankX, enemyTankY, 8)
596 fire_power += power_change
597
598 power(fire_power)
599
600 barrier(xlocation, randomHeight, barrier_width)
601 gameDisplay.fill(green,
602 rect=[0, display_height - ground_height, display_width, ground_height])
603 pygame.display.update()
604
605 clock.tick(FPS)
606
607 damage = e_fireShell(enemy_gun, enemyTankX, enemyTankY, 8, 50, xlocation, barrier_width,
608 randomHeight, mainTankX, mainTankY)
609 player_health -= damage
610
611 elif event.key == pygame.K_a:
612 power_change = -1
613 elif event.key == pygame.K_d:
614 power_change = 1
615
616 elif event.type == pygame.KEYUP:
617 if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
618 tankMove = 0
619
620 if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
621 changeTur = 0
622
623 if event.key == pygame.K_a or event.key == pygame.K_d:
624 power_change = 0
625
626 mainTankX += tankMove
627
628 currentTurPos += changeTur
629
630 if currentTurPos > 8:
631 currentTurPos = 8
632 elif currentTurPos < 0:
633 currentTurPos = 0
634
635 if mainTankX - (tankWidth / 2) < xlocation + barrier_width:
636 mainTankX += 5
637
638 gameDisplay.fill(black)
639 health_bars(player_health, enemy_health)
640 gun = tank(mainTankX, mainTankY, currentTurPos)
641 enemy_gun = enemy_tank(enemyTankX, enemyTankY, 8)
642
643 fire_power += power_change
644
645 if fire_power > 100:
646 fire_power = 100
647 elif fire_power < 1:
648 fire_power = 1
649
650 power(fire_power)
651
652 barrier(xlocation, randomHeight, barrier_width)
653 gameDisplay.fill(green, rect=[0, display_height - ground_height, display_width, ground_height])
654 pygame.display.update()
655
656 if player_health < 1:
657 game_over()
658 elif enemy_health < 1:
659 you_win()
660 clock.tick(FPS)
661
662 pygame.quit()
663 quit()
664
665 game_intro()
666 gameLoop()